package javax.slee.management;

import javax.slee.ComponentID;
import javax.slee.InvalidArgumentException;
import javax.slee.UnrecognizedComponentException;
import javax.slee.facilities.Level;
import javax.slee.facilities.TraceLevel;

/**
 * The <code>TraceMBean</code> interface defines the management interface for the SLEE
 * tracing subsystem.  Using the <code>TraceMBean</code>, a management client may get or
 * set the trace filter levels used to control whether or not the Trace MBean generates
 * {@link TraceNotification TraceNotifications} for trace messages emitted by SLEE
 * components such as SBBs, profiles, and resource adaptor entities.
 * <p>
 * The JMX Object Name of a <code>TraceMBean</code> object is specified by the
 * {@link #OBJECT_NAME} constant.  Alternatively, the Object Name can be obtained by
 * a management client via the {@link SleeManagementMBean#getTraceMBean()} method.
 * <p>
 * <b>Trace Filter Levels</b><br>
 * A {@link TraceLevel trace filter level} may be assigned to each
 * {@link javax.slee.facilities.Tracer tracer} used by a particular {@link NotificationSource}.
 * Different trace filter levels may be assigned for a tracer with the same name but associated
 * with different notification sources.  For example, for the tracer named
 * <code>"com.foo"</code>, it is possible to set the trace filter level the tracer
 * to <code>TraceLevel.FINEST</code> for some SBB in a service and <code>TraceLevel.INFO</code>
 * for another SBB in the same service, as each SBB is a unique notification source.
 * <p>
 * When a message is emitted to a tracer, the effective trace filter level is used to
 * determine whether or not the Trace MBean generates a {@link TraceNotification}. The
 * effective trace filter level of a tracer is equal to the trace filter level assigned
 * to the tracer for the notification source in which the <code>Tracer</code> object was
 * created.  If a trace filter level has not been assigned to that tracer, the effective
 * trace filter level is inherited from its nearest ancestor in the tracer hierarchy
 * that has an assigned trace filter level.  The root tracer of each possible notification
 * source always has a trace filter level assigned to it, which initially defaults to
 * {@link TraceLevel#INFO}.  A SLEE implementation should (but is not required to)
 * persist any trace filter levels set during normal operation, so that trace filter levels
 * can be restored upon a complete server restart.
 * <p>
 * As an example, assume the following management operations (only) have been invoked
 * on the Trace MBean:
 * <p><ul><code>
 *   SbbNotification sbb = ...<br>
 *   setTraceLevel(sbb, "", TraceLevel.INFO);<br>
 *   setTraceLevel(sbb, "com.foo", TraceLevel.FINEST);
 * </code></ul><p>
 * The following management operations would return effective trace levels as indicated:
 * <p><ul><code>
 *   getTraceLevel(sbb, "") == TraceLevel.INFO<br>
 *   getTraceLevel(sbb, "com") == TraceLevel.INFO<br>
 *   getTraceLevel(sbb, "com.foo") == TraceLevel.FINEST<br>
 *   getTraceLevel(sbb, "com.foo.bar") == TraceLevel.FINEST<br>
 * </code></ul>
 * <p>
 * When a trace message is emitted to a tracer, if the trace level of the trace message is
 * greater than or equal to the effective trace filter level of the tracer for the notification
 * source it was created for, a {@link TraceNotification} will be generated by the Trace MBean
 * and delivered to any notification listeners.  Otherwise the trace message is silently
 * discarded by the SLEE.
 * <p>
 * <b>Notifications</b><br>
 * Since a <code>TraceMBean</code> object can emit trace notifications, it is required that
 * the <code>TraceMBean</code> object implement the <code>javax.management.NotificationBroadcaster</code>
 * interface.
 * <p>
 * <b>Note:</b> In SLEE 1.0 a Trace MBean emitted only one type of notification,
 * defined by {@link #TRACE_NOTIFICATION_TYPE}.  As of SLEE 1.1, a <code>TraceMBean</code>
 * object may emit trace notifications of different types, depending on the notification
 * source of the tracer used to emit the trace message.  The SLEE-defined classes that
 * implement {@link NotificationSource} each specify the type of trace notification
 * that is generated for the notification source.
 */
public interface TraceMBean {
    /**
     * The JMX Object Name string of the SLEE Trace MBean, equal to the string
     * "javax.slee.management:name=Trace".
     * @since SLEE 1.1
     */
    public static final String OBJECT_NAME = "javax.slee.management:name=Trace";

    /**
     * The notification type of {@link TraceNotification Trace} notifications
     * emitted by this MBean.  The notification type is equal to the string
     * "javax.slee.management.trace".
     * @deprecated Different notification types may be generated by the Trace MBean depending
     * on where the trace message was emitted.  The SLEE-defined classes that implement
     * {@link NotificationSource} each specify a particular trace notification type for the
     * notification source.
     */
    public static final String TRACE_NOTIFICATION_TYPE = "javax.slee.management.trace";

    /**
     * Set the trace filter level for a particular component.  The <code>TraceMBean</code>
     * only generates trace notifications if the trace level of a trace message
     * generated by a component is equal to or greater than the trace filter level
     * set for that component.
     * <p>
     * The default trace filter level for a component is {@link Level#OFF},
     * ie. trace notifications are never generated for the component unless the trace
     * filter level is explicitly set to a different level.
     * @param id the identifier of the component.
     * @param traceLevel the new trace filter level for the component.
     * @throws NullPointerException if <code>id</code> is <code>null</code>.
     * @throws UnrecognizedComponentException if <code>id</code> is not a recognizable
     *        <code>ComponentID</code> object for the SLEE or it does not correspond
     *        with a component installed in the SLEE.
     * @throws ManagementException if the trace level could not be set due to a
     *        system-level failure.
     * @deprecated This method uses a <code>ComponentID</code> to identify a notification
     *        source and thus is not compatible with the changes made to the tracing
     *        subsystem in SLEE 1.1.  It has been replaced with {@link #setTraceLevel(NotificationSource, String, TraceLevel)}.
     */
    public void setTraceLevel(ComponentID id, Level traceLevel)
        throws NullPointerException, UnrecognizedComponentException, ManagementException;

    /**
     * Get the trace filter level for a particular component.
     * <p>
     * The default trace filter level for a component is {@link Level#OFF},
     * ie. trace notifications are never generated for the component unless the trace
     * filter level is explicitly set to a different level.
     * @param id the identifier of the component.
     * @return the trace filter level for the component.
     * @throws NullPointerException if <code>id</code> is <code>null</code>.
     * @throws UnrecognizedComponentException if <code>id</code> is not a recognizable
     *        <code>ComponentID</code> object for the SLEE or it does not correspond
     *        with a component installed in the SLEE.
     * @throws ManagementException if the trace level could not be set due to a
     *        system-level failure.
     * @deprecated This method uses a <code>ComponentID</code> to identify a notification
     *        source and thus is not compatible with the changes made to the tracing
     *        subsystem in SLEE 1.1.  It has been replaced with {@link #getTraceLevel(NotificationSource, String)}.
     */
    public Level getTraceLevel(ComponentID id)
        throws NullPointerException, UnrecognizedComponentException, ManagementException;

    /**
     * Get the names of the tracers that have been requested by the specified notification source.
     * @param notificationSource the notification source.
     * @return an array of tracer names corresponding to the tracers that have been requested by
     *        the specified notification source.
     * @throws NullPointerException if <code>notificationSource</code> is <code>null</code>.
     * @throws UnrecognizedNotificationSourceException if <code>notificationSource</code>
     *        does not identify a notification source recognizable by the SLEE.
     * @throws ManagementException if the tracer names could not be obtained due to a
     *        system-level failure.
     * @since SLEE 1.1
     */
    public String[] getTracersUsed(NotificationSource notificationSource)
        throws NullPointerException, UnrecognizedNotificationSourceException, ManagementException;

    /**
     * Set the trace filter level of the specified tracer for the specified notification
     * source to the specified trace level.
     * @param notificationSource the notification source.
     * @param tracerName the name of the tracer for which the trace level should be assigned.
     *        The empty string denotes the root tracer.
     * @param level the trace filter level to be assigned to the tracer.
     * @throws NullPointerException if any argument is <code>null</code>.
     * @throws UnrecognizedNotificationSourceException if <code>notificationSource</code>
     *        does not identify a notification source recognizable by the SLEE.
     * @throws InvalidArgumentException if <code>tracerName</code> is not a valid tracer name.
     * @throws ManagementException if the trace filter level could not be set due to a
     *        system-level failure.
     * @since SLEE 1.1
     */
    public void setTraceLevel(NotificationSource notificationSource, String tracerName, TraceLevel level)
        throws NullPointerException, UnrecognizedNotificationSourceException,
               InvalidArgumentException, ManagementException;

    /**
     * Unset the trace filter level of the specified tracer for the specified notification
     * source.  This method removes any trace filter level previously assigned to the tracer
     * so that the effective trace filter level of that tracer is subsequently obtained from
     * the tracer's parent tracer.
     * <p>
     * This method has no effect, and returns without error, if no trace filter level is
     * currently assigned to the specified tracer.
     * <p>
     * The trace filter level for the root tracer (identified by the empty string) cannot be
     * unset.
     * @param notificationSource the notification source.
     * @param tracerName the name of the tracer for which the trace level should be unset.
     * @throws NullPointerException if any argument is <code>null</code>.
     * @throws UnrecognizedNotificationSourceException if <code>notificationSource</code>
     *        does not identify a notification source recognizable by the SLEE.
     * @throws InvalidArgumentException if <code>tracerName</code> is not a valid tracer name, or
     *        is the empty string (denoting the root tracer).
     * @throws ManagementException if the trace filter level could not be unset due to a
     *        system-level failure.
     * @since SLEE 1.1
     */
    public void unsetTraceLevel(NotificationSource notificationSource, String tracerName)
        throws NullPointerException, UnrecognizedNotificationSourceException,
               InvalidArgumentException, ManagementException;

    /**
     * Get the names of the tracers for which a trace filter level has been assigned
     * for the specified notification source.  This method returns the list of tracer names
     * for which trace filter levels have been assigned for the notification source using the
     * {@link #setTraceLevel(NotificationSource, String, TraceLevel) setTraceLevel} method,
     * and for which the trace filter level has not yet been unset using the
     * {@link #unsetTraceLevel(NotificationSource, String) unsetTraceLevel} method.
     * @param notificationSource the notification source.
     * @throws NullPointerException if <code>notificationSource</code> is <code>null</code>.
     * @throws UnrecognizedNotificationSourceException if <code>notificationSource</code>
     *        does not identify a notification source recognizable by the SLEE.
     * @throws ManagementException if the tracer names could not be obtained due to a
     *        system-level failure.
     * @since SLEE 1.1
     */
    public String[] getTracersSet(NotificationSource notificationSource)
        throws NullPointerException, UnrecognizedNotificationSourceException, ManagementException;

    /**
     * Get the effective trace filter level of the specified tracer for the specified
     * notification source.  Note that the returned trace level may not be directly assigned
     * to the specified tracer, but may have been obtained from the tracer's nearest
     * ancestor that has a trace filter level assigned.
     * <p>
     * The default trace filter level for the root tracer for all tracers is {@link TraceLevel#INFO}.
     * Thus the default effective trace filter level for all tracers obtained by a notification
     * source is also {@link TraceLevel#INFO}.
     * @param notificationSource the notification source.
     * @param tracerName the name of the tracer for which the effective trace level should be
     *        obtained.  The empty string denotes the root tracer.
     * @return the current effective trace filter level for the tracer.
     * @throws NullPointerException if any argument is <code>null</code>.
     * @throws UnrecognizedNotificationSourceException if <code>notificationSource</code>
     *        does not identify a notification source recognizable by the SLEE.
     * @throws InvalidArgumentException if <code>tracerName</code> is not a valid tracer name.
     * @throws ManagementException if the trace filter level could not be obtained due to a
     *        system-level failure.
     * @since SLEE 1.1
     */
    public TraceLevel getTraceLevel(NotificationSource notificationSource, String tracerName)
        throws NullPointerException, InvalidArgumentException,
               UnrecognizedNotificationSourceException, ManagementException;
}
